package com.yeban.javase.day19.answer.test4;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @Desc 服务端
 * @Author yeban
 * @Date 2025/11/4
 */
public class TCPServer {

    public static void main(String[] args) {
        System.out.println("---------- Server ----------");
        // 存储所有接入的客户端容器
        CopyOnWriteArrayList<Socket> clients = new CopyOnWriteArrayList<>();
        // 线程池
        ThreadPool pool = new ThreadPool(ThreadPoolConfig.MAX_POOL_SIZE, ThreadPoolConfig.QUEUE_SIZE);
        // 最多能执行的任务数
        final int max = ThreadPoolConfig.MAX_POOL_SIZE + ThreadPoolConfig.QUEUE_SIZE;

        ServerSocket ss = null;
        try {
            // 创建服务器
            ss = new ServerSocket(8899);
            while(true) {
                // 等待客户端连入
                Socket socket = ss.accept();
                clients.add(socket);
                // 为每一个接入的客户端,创建一个话务员
                ServerTasker serverTasker = new ServerTasker(socket,clients, Thread.currentThread());
                pool.execute(serverTasker);
                System.out.println(socket.getRemoteSocketAddress() + "已上线~");

                if(clients.size() == max) {
                    ss.close();
                    ss = null;
                    // 阻塞当前main主线程
                    LockSupport.park();
                    // 确保有足够的时间，将线程归还线程池中
                    try {
                        TimeUnit.MILLISECONDS.sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    // 此时有客户端释放，允许继续加入socket
                    ss = new ServerSocket(8899);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
